import proj4 from "./proj4";
const ee = 0.006693421622965823;
const R = 6378245;
//proj4.defs('EPSG:4479','+proj=geocent +datum=WGS84 +units=m');
proj4.defs("EPSG:4479", "+proj=geocent +ellps=GRS80 +units=m +no_defs +type=crs");
proj4.defs("EPSG:4979", "+proj=longlat +datum=WGS84 +no_defs +type=crs");
proj4.defs['4326'] = proj4.defs['EPSG:4326'];
proj4.defs['4269'] = proj4.defs['EPSG:4269'];
proj4.defs['3857'] = proj4.defs['EPSG:3857'];
proj4.defs['4479'] = proj4.defs['EPSG:4479'];
function isInChinaBbox(coord) {
    const [lon, lat] = coord;
    return lon >= 72.004 && lon <= 137.8347 && lat >= 0.8293 && lat <= 55.8271;
}
function transformLon(x, y) {
    let ret = 300 + x + 2 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
    ret += (20 * Math.sin(6 * x * Math.PI) + 20 * Math.sin(2 * x * Math.PI)) * 2 / 3;
    ret += (20 * Math.sin(x * Math.PI) + 40 * Math.sin(x / 3 * Math.PI)) * 2 / 3;
    ret += (150 * Math.sin(x / 12 * Math.PI) + 300 * Math.sin(x / 30 * Math.PI)) * 2 / 3;
    return ret;
}
function transformLat(x, y) {
    let ret = -100 + 2 * x + 3 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
    ret += (20 * Math.sin(6 * x * Math.PI) + 20 * Math.sin(2 * x * Math.PI)) * 2 / 3;
    ret += (20 * Math.sin(y * Math.PI) + 40 * Math.sin(y / 3 * Math.PI)) * 2 / 3;
    ret += (160 * Math.sin(y / 12 * Math.PI) + 320 * Math.sin(y * Math.PI / 30)) * 2 / 3;
    return ret;
}
function delta(coord) {
    const [lon, lat] = coord;
    let dLon = transformLon(lon - 105, lat - 35);
    let dLat = transformLat(lon - 105, lat - 35);

    const radLat = lat / 180 * Math.PI;
    let magic = Math.sin(radLat);

    magic = 1 - ee * magic * magic;

    const sqrtMagic = Math.sqrt(magic);
    dLon = (dLon * 180) / (R / sqrtMagic * Math.cos(radLat) * Math.PI);
    dLat = (dLat * 180) / ((R * (1 - ee)) / (magic * sqrtMagic) * Math.PI);

    return [dLon, dLat];
}

// 加密成gcj02;
proj4.encryption = function (coord) {
    const [lon, lat] = coord;
    if (!isInChinaBbox(coord)) return [lon, lat];
    const d = delta([lon, lat]);
    return [lon + d[0], lat + d[1]];
}
// 解密成84
proj4.decrypt = function (coord) {
    const [lon, lat] = coord;
    if (!isInChinaBbox(coord)) return [lon, lat];

    let [wgsLon, wgsLat] = [lon, lat];

    let tempPoint = proj4.encryption([wgsLon, wgsLat]);

    let dx = tempPoint[0] - lon;
    let dy = tempPoint[1] - lat;

    while (Math.abs(dx) > 1e-6 || Math.abs(dy) > 1e-6) {
        wgsLon -= dx;
        wgsLat -= dy;

        tempPoint = proj4.encryption([wgsLon, wgsLat]);
        dx = tempPoint[0] - lon;
        dy = tempPoint[1] - lat;
    }

    return [wgsLon, wgsLat];
}
//统一高程坐标和经纬度坐标
proj4.unify = function (position) {
    position[2] = position[2] / 111000;
    return position;//todo 精确计算
}
proj4.scale = function (lonlat) {
    let scaleY=111319.49079327358;//球半经算的，定值
    let s=Math.cos(lonlat[1]*Math.PI/180);
    let scaleX=scaleY*s;
    return [scaleX,scaleY];
}
proj4.isInChinaBbox = isInChinaBbox;
/**
 * 坐标转换函数
 * @memberof w
 * @method proj
 * @param {String}  source 源坐标系，eg:"EPSG:4326"。
 * @param {String} target 目标坐标系，eg:"EPSG:3857"。
 * @param {vec|Array(3)} coord 源坐标，eg:[120,30,0]。
 * @returns {vec|Array(3)} 转换后坐标,eg:[120,30,0]。
 * @example
 * let a=w.proj("EPSG:4326","EPSG:3395",[120,30,0])
 * console.log(a);
 * let b=w.proj("EPSG:3395","EPSG:4326",a)
 * console.log(b)
 */
/**
 * @namespace w
 */
const proj = proj4;
export { proj };
//内置定义
//定义使用 "EPSG:4326" "EPSG:3857" "EPSG:4479"
// w.proj.defs("EPSG:3395","+proj=geocent +datum=WGS84")
// let a=w.proj("EPSG:4326","EPSG:3395",[120,30,0])
// console.log(a);
// let b=w.proj("EPSG:3395","EPSG:4326",a)
// console.log(b)
//直接使用
//w.project("EPSG:4326","+proj=geocent +datum=WGS84",[120,30,0])
